#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "config.h"
#include "startwindow.h"
#include "rankdialog.h"
#include "enemyplaneh.h"

#include <QIcon>
#include <QPainter>
#include <QTimer>
#include <QKeyEvent>
#include <ctime>
#include "QDebug"
#include "ranklogin.h"
#include "heroplane.h"
#include "levelplane.h"
#include "light.h"


//namespace constant
int Plane::level=1;
int MainWindow::dead=0;
char buffer[256];

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //调用初始化场景(已改变调用方式)

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initSence()
{
    //设置窗口的固定尺寸
    setFixedSize(Game_WIDTH,Game_HEIGHT);

    //设置标题
    setWindowTitle(Game_TITLE);

    //加载图标
    setWindowIcon(QIcon(Game_ICON));

    //定时器设置
    m_Timer.setInterval(Game_RATE);

    //获取键盘焦点
    this->grabKeyboard();

    //随机数种子
    srand((unsigned int)time(0));

    //去到Start界面的信号与槽事件
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(on_pushButton_clicked(bool)));

    sf1 = new startwindow();

    m_recorder = 0;


}

void MainWindow::playGame()
{
    //启动定时器
    m_Timer.start();

    //监听定时器发送的信号
    connect(&m_Timer , &QTimer::timeout,[=](){
        //chech game status
        if(!ifStop)
        {
            //更新游戏中元素的坐标
            updatePosition();
            //敌机出场
            enemyToWindow();
            //更新游戏中元素的坐标
            updatePosition();
            //绘制到屏幕中
            update();
            //碰撞检测
            collisionDetection();
            //启动背景音乐
            //QSound::play(SOUND_BACKGROUND);
            //升级后的碰撞
            levelcollisionDetection();
            //飞机发光
            levelup();
            change();

            /* real time 显示 */
            sprintf(buffer, "Distance: %im\n",m_map.distance);
            ui->Distancelabel->setText(buffer);
            sprintf(buffer, "Level: %i\n",Plane::level);
            ui->Levellabel->setText(buffer);
        }
    });


}

void MainWindow::enemyToWindow()
{
    //数组对象
    m_recorder++;
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_recorder < m_enemys[i].interval)
        {
            return;
        }
    }


    m_recorder = 0;

    for(int i = 0 ; i< ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free)
        {
            //敌机空闲状态改为false
            m_enemys[i].m_Free = false;

            //设置坐标
            m_enemys[i].m_X = rand() % (Left_boundary - Right_boundary - m_enemys[i].m_Rect.width()) + Right_boundary;
            m_enemys[i].m_Y = -m_enemys[i].m_Rect.height();

            break;
        }
    }
}

void MainWindow::updatePosition()
{
    //更新地图的坐标
    m_map.mapPosition();
    //初始飞机发射子弹

    for(int i = 0;i < BULLET_NUM;i++)
    {
        //如果非空闲，计算发射位置
       if(!m_hero.m_bullets[i].m_Free)
        {
            m_hero.m_bullets[i].updatePosition();
        }
    }
       //初始升级飞机发射子弹
       for(int i = 0;i < BULLET_NUM;i++)
       {
           //如果非空闲，计算发射位置
          if(!(m_level).m_bullets[i].m_Free)
           {
               (m_level).m_bullets[i].updatePosition();
           }
       //测试子弹
      // temp_Bullet.m_Free = false;
       //temp_Bullet.updatePosition();

    }

     //敌机坐标计算
    for(int i = 0 ; i< ENEMY_NUM;i++)
    {
        //非空闲敌机 更新坐标
       if(m_enemys[i].m_Free == false)
       {
          m_enemys[i].updatePosition();
       }
    }



            //计算爆炸播放的图片
                for(int i = 0 ; i < BOMB_NUM;i++)
                {
                    if(m_bombs[i].m_Free == false)
                    {
                       m_bombs[i].updateInfo();
                    }
                }

     //计算guang播放的图片
                for(int i = 0 ; i < LIGHT_NUM;i++)
                {
                    if(m_lights[i].m_Free == false)
                    {
                       m_lights[i].updateInfo();
                    }
                }


  //计算敌机子弹坐标
if(dead>Game_levelup*2)
{
    for(int i=0;i<ENEMY_NUM;i++)
    {
         if(m_enemys[i].m_Free == false)
         {
             for(int j = 0 ;j < BULLET_NUM;j++)
             {
                 //如果子弹状态为非空闲，计算发射位置
                 if(!m_enemys[i].m_bullets[j].m_Free)
                 {
                     m_enemys[i].m_bullets[j].updatePosition();
                 }
             }
         }
    }
}


}



void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

//绘制地图
    painter.drawPixmap(0,m_map.m_map1_posY,m_map.m_map1);
    painter.drawPixmap(0,m_map.m_map2_posY,m_map.m_map2);

//绘制两架飞机的形式
   if((m_hero.m_X>=Right_boundary)&&(m_hero.m_X<=Left_boundary))
   {
       //绘制英雄飞机
       painter.drawPixmap(m_hero.m_X,m_hero.m_Y,m_hero.m_Plane);

   }

   //绘制升级飞机
   else if(m_hero.m_X<Right_boundary)
   {
       painter.drawPixmap(m_level.m_X,m_level.m_Y,m_level.m_Plane);
  }

//绘制子弹
   for(int i = 0;i < BULLET_NUM;i++)
   {
       //如果非空闲，绘制
        if(!m_hero.m_bullets[i].m_Free)
        {
            painter.drawPixmap(m_hero.m_bullets[i].m_X, m_hero.m_bullets[i].m_Y, m_hero.m_bullets[i].m_Bullet);
        }
    }

//绘制升级子弹
    for(int i = 0;i < BULLET_NUM;i++)
    {
        //如果非空闲，绘制
        if(!m_level.m_bullets[i].m_Free)
        {
            painter.drawPixmap(m_level.m_bullets[i].m_X,m_level.m_bullets[i].m_Y,m_level.m_bullets[i].m_Bullet);
        }
    }

//绘制敌机
            for(int i = 0 ; i< ENEMY_NUM;i++)
            {
                if(m_enemys[i].m_Free == false)
                {
                    painter.drawPixmap(m_enemys[i].m_X,m_enemys[i].m_Y,m_enemys[i].m_enemy);
                }
            }

//绘制敌机子弹
if(dead>Game_levelup*2)
{
    for(int i = 0 ;i < ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free == false)
        {
            for(int j=0;j<BULLET_NUM;j++)
            {
                //如果子弹状态为非空闲，计算发射位置
                if(!m_enemys[i].m_bullets[i].m_Free)
                {
                    painter.drawPixmap(m_enemys[i].m_bullets[j].m_X, m_enemys[i].m_bullets[j].m_Y, m_enemys[i].m_bullets[j].m_Bullet);
                }
            }
        }

    }
}

//计算子弹坐标
for(int i = 0 ;i < BULLET_NUM;i++)
{
 if(!m_hero.m_bullets[i].m_Free)
   {
        painter.drawPixmap(m_hero.m_bullets[i].m_X,m_hero.m_bullets[i].m_Y,m_hero.m_bullets[i].m_Bullet);
   }
}


//绘制爆炸图片
                for(int i = 0 ; i < BOMB_NUM;i++)
                {
                    if(m_bombs[i].m_Free == false)
                    {
                       painter.drawPixmap(m_bombs[i].m_X,m_bombs[i].m_Y,m_bombs[i].m_pixArr[m_bombs[i].m_index]);
                    }
                }


    //测试子弹
    //    painter.drawPixmap(temp_Bullet.m_X,temp_Bullet.m_Y,temp_Bullet.m_Bullet);
//绘制发光图片
            for(int i = 0 ; i < LIGHT_NUM;i++)
            {
                if(m_lights[i].m_Free == false)
                {
                   painter.drawPixmap(m_lights[i].m_X,m_lights[i].m_Y,m_lights[i].m_pixArr[m_lights[i].m_index]);
                }
            }
}



void MainWindow::collisionDetection()
{
    //遍历所有非空闲的敌机
    for(int i = 0 ;i < ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free)
        {
            //空闲飞机 跳转下一次循环
            continue;
        }

        //遍历所有 非空闲的子弹
        for(int j = 0 ; j < BULLET_NUM;j++)
        {
            if(m_hero.m_bullets[j].m_Free)
            {
                //空闲子弹 跳转下一次循环
                continue;
            }

            //如果子弹矩形框和敌机矩形框相交，发生碰撞，同时变为空闲状态即可
            if(m_enemys[i].m_Rect.intersects(m_hero.m_bullets[j].m_Rect))
            {
                ++dead;
                    qDebug()<<dead<<endl;
//                qDebug() <<dead<<endl;
                m_enemys[i].m_Free = true;
                m_hero.m_bullets[j].m_Free = true;

                //播放爆炸效果
                for(int k = 0 ; k < BOMB_NUM;k++)
                {
                    if(m_bombs[k].m_Free)
                    {
                        //爆炸状态设置为非空闲
                        m_bombs[k].m_Free = false;
                        //更新坐标

                        m_bombs[k].m_X = m_enemys[i].m_X;
                        m_bombs[k].m_Y = m_enemys[i].m_Y;
                        break;
                    }
                }
}
        }
        //如果我机矩形框和敌机矩形框相交，发生碰撞，同时变成空闲状态
        if(m_hero.m_Rect.intersects(m_enemys[i].m_Rect))
        {
            m_enemys[i].m_Free = true;
            m_hero.m_Free = true;
            //使我机消失
            m_hero.m_X = 10000;

            //播放爆炸效果
            for(int k = 0 ; k < BOMB_NUM;k++)
            {
                if(m_bombs[k].m_Free)
                {
                    //爆炸状态设置为非空闲
                    m_bombs[k].m_Free = false;
                    //更新坐标

                    m_bombs[k].m_X = m_enemys[i].m_X;
                    m_bombs[k].m_Y = m_enemys[i].m_Y;

                    break;
                }
            }

            //exit and stop game
            ifStop = true;
            this->releaseKeyboard();

            //call compare function and judgy
            if(sf3->judgeRanks(Plane::level*m_map.distance))
            {
                this->releaseKeyboard();

                sf2 = new RankLogin(Plane::level*m_map.distance);
                sf2->show();

                sf2->setDistance(m_map.distance);

            }else{

                //创建全局变量 start界面的对象，
                //若sf1是局部变量，则不会显示第二个界面，因为调用完局部变量就被释放掉了
                //sf1是在第一个界面头文件里定义的全局变量
                sf1->show();
           }

            //delete当前的窗体
            this->close();

        }


    }

}

//升级飞机碰撞
void MainWindow::levelcollisionDetection()
{
    //遍历所有非空闲的敌机
    for(int i = 0 ;i < ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free)
        {
            //空闲飞机 跳转下一次循环
            continue;
        }

        //遍历所有 非空闲的子弹
        for(int j = 0 ; j < BULLET_NUM;j++){

            //如果子弹矩形框和敌机矩形框相交，发生碰撞，同时变为空闲状态即可
            if(m_enemys[i].m_Rect.intersects(m_level.m_bullets[j].m_Rect))
            {
                ++dead;

                m_enemys[i].m_Free = true;
                m_level.m_bullets[j].m_Free = true;

                //播放爆炸效果
                                for(int k = 0 ; k < BOMB_NUM;k++)
                                {
                                    if(m_bombs[k].m_Free)
                                    {
                                        //爆炸状态设置为非空闲
                                        m_bombs[k].m_Free = false;

                                        //更新坐标

                                        m_bombs[k].m_X = m_enemys[i].m_X;
                                        m_bombs[k].m_Y = m_enemys[i].m_Y;
                                        break;
                                    }
                                }
            }
        }
        if(m_level.m_Rect.intersects(m_enemys[i].m_Rect))
        {
            m_enemys[i].m_Free = true;
            m_level.m_Free = true;

            //使我机消失
            m_level.m_X = 10000;


            //播放爆炸效果
            for(int k = 0 ; k < BOMB_NUM;k++)
            {
                if(m_bombs[k].m_Free)
                {
                    //爆炸状态设置为非空闲
                    m_bombs[k].m_Free = false;
                    //更新坐标

                    m_bombs[k].m_X = m_enemys[i].m_X;
                    m_bombs[k].m_Y = m_enemys[i].m_Y;
                    break;
                }
            }

            //exit and stop game
            ifStop = true;
            this->releaseKeyboard();

            //call compare function and judgy
            if(sf3->judgeRanks(Plane::level*m_map.distance))
            {
                this->releaseKeyboard();

                sf2 = new RankLogin(Plane::level*m_map.distance);
                sf2->show();

                sf2->setDistance(m_map.distance);

            }else{

                //创建全局变量 start界面的对象，
                //若sf1是局部变量，则不会显示第二个界面，因为调用完局部变量就被释放掉了
                //sf1是在第一个界面头文件里定义的全局变量
                sf1->show();
           }

            //delete当前的窗体
            this->close();
          }
    }
}

void MainWindow::overBoundDetect(int &x, int &y, int w, int h)
{
    if(x <= Right_boundary )
    {
        x = Right_boundary;
    }

    if(x >= Left_boundary - w)
    {
        x = Left_boundary - w;
    }
    if(y <= 0)
    {
        y = 0;
    }
    if(y >= Game_HEIGHT - h)
    {
        y = Game_HEIGHT - h;
    }
}

void MainWindow::keyPressEvent(QKeyEvent *ev)
{
    if((m_hero.m_X>=Right_boundary)&&(m_hero.m_X<=Left_boundary))
    {
        //get the current position
        int x = m_hero.m_X;
        int y = m_hero.m_Y;
        //change value
        switch (ev->key()) {
        case Qt::Key_Up:
            y-=MOVE_SPEED;
            break;
        case Qt::Key_Down:
            y+=MOVE_SPEED;
            break;
        case Qt::Key_Right:
            x+=MOVE_SPEED;
            break;
        case Qt::Key_Left:
            x-=MOVE_SPEED;
            break;
        case Qt::Key_Space:
        {
           m_hero.shoot();
            break;
        }
        default:
            break;
            }
        //边界检测
        overBoundDetect(x,y, m_hero.m_Rect.width(), m_hero.m_Rect.height());
        //move
         m_hero.setPosition(x,y);
    }
    //控制升级飞机
    else
    {
        //get the current position
        int x = m_level.m_X;
        int y = m_level.m_Y;
        //change value
        switch (ev->key()) {
        case Qt::Key_Up:
            y-=MOVE_SPEED;
            break;
        case Qt::Key_Down:
            y+=MOVE_SPEED;
            break;
        case Qt::Key_Right:
            x+=MOVE_SPEED;
            break;
        case Qt::Key_Left:
            x-=MOVE_SPEED;
            break;
        case Qt::Key_Space:
        {
           m_level.shoot();
           //射击音效
          // QSound::play(SOUND_SHOOT);
            break;
        }
        default:
            break;
            }
        //边界检测
        overBoundDetect(x,y, m_level.m_Rect.width(), m_level.m_Rect.height());
        //move
         m_level.setPosition(x,y);
    }

}

void MainWindow::on_pushButton_clicked()
{
    //stop game
    ifStop = true;

    this->releaseKeyboard();

    //call compare function and judgy
    if(sf3->judgeRanks(Plane::level*m_map.distance))
    {
        this->releaseKeyboard();

        sf2 = new RankLogin(Plane::level*m_map.distance);
        sf2->show();

        sf2->setDistance(m_map.distance);

    }else{

        //创建全局变量 start界面的对象，
        //若sf1是局部变量，则不会显示第二个界面，因为调用完局部变量就被释放掉了
        //sf1是在第一个界面头文件里定义的全局变量
        sf1->show();
   }

    //delete当前的窗体
    this->close();
}

void MainWindow::on_StopButton_clicked()
{

    if(!ifStop)
    {//to stop
        ifStop=true;

        ui->StopButton->setText("Continue");
    }else{
        //to continue
        ifStop=false;

         ui->StopButton->setText("Stop");
    }

}

void MainWindow::shine()
{
    if(dead==Game_levelup)
    {
        for(int k = 0 ; k < LIGHT_NUM;k++)
        {
            if(m_lights[k].m_Free)
            {
                //光标状态设置为非空闲
                m_lights[k].m_Free = false;

                //更新坐标
                m_lights[k].m_X =  m_hero.m_X;
                m_lights[k].m_Y =  m_hero.m_Y;
                break;
            }
         }

    }

}

//飞机升级换机
void MainWindow::levelup()
{

            if(dead==Game_levelup)
            {

                  Plane::level++;
//                  qDebug()<<Plane::level<<endl;
                  shine();
                   dead++;
                  //创建临时指
                  //升级后销毁原飞机
                  int temp=m_hero.m_X;
                  m_hero.m_X=Right_boundary-10;
                  m_level.m_Y=m_hero.m_Y;
                  m_level.m_X=temp;
            }

}

//系统配置数据
void MainWindow::change()
{
    if(dead<Game_levelup*1)
    {
         m_map.m_scroll_speed=MAP_SCROLL_SPEED;
         for(int i=0;i<ENEMY_NUM;i++)
         {
             m_enemys[i].m_Speed=ENEMY_SPEED;
             m_enemys[i].interval=ENEMY_INTERVAL;
             m_enemys[i].shoot();

         }
    }
    if(dead<Game_levelup*2 && dead>=Game_levelup*1)
    {
         m_map.m_scroll_speed=MAP_SCROLL_SPEED;
         for(int i=0;i<ENEMY_NUM;i++)
         {
             m_enemys[i].m_Speed=ENEMY_SPEED*2;
             m_enemys[i].interval=(ENEMY_INTERVAL*2/3);

         }
    }
    if(dead>=Game_levelup*2)
    {
         m_map.m_scroll_speed=MAP_SCROLL_SPEED;
         for(int i=0;i<ENEMY_NUM;i++)
         {
             m_enemys[i].m_Speed=ENEMY_SPEED*2;
             m_enemys[i].interval=(ENEMY_INTERVAL*1/3);

 //             qDebug()<<dead<<endl;
         }
    }
}
